package com.thebeastshop.hotlink.proxy;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSON;
import com.jd.platform.hotkey.client.callback.JdHotKeyStore;
import com.thebeastshop.hotlink.manager.HotlinkInterfaceKeyManager;
import com.thebeastshop.hotlink.util.MethodUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class HotlinkProxy implements InvocationHandler {

    private Object sourceBean;

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    public HotlinkProxy(Object sourceBean) {
        this.sourceBean = sourceBean;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        try{
            Class declaredInterfaceClass = method.getDeclaringClass();
            if (ObjectUtil.isNull(declaredInterfaceClass)){
                String errorMsg = StrUtil.format("[Hotlink] 没有找到类[{}]中方法[{}]的接口定义", sourceBean.getClass().getName(), method.getName());
                throw new RuntimeException(errorMsg);
            }

            String keyPrefix = MethodUtil.getInterfaceMethodStr(declaredInterfaceClass, method);

            if (HotlinkInterfaceKeyManager.containsKey(keyPrefix)){
                String key = getFinalKey(keyPrefix, args);
                if (JdHotKeyStore.isHotKey(key)){
                    Object value = JdHotKeyStore.get(key);
                    if(ObjectUtil.isNull(value)) {
                        log.info("[Hotlink] key[{}]已经成为热点,热点参数为:{}", key, JSON.toJSONString(args));
                        Object result = method.invoke(sourceBean, args);
                        if (ObjectUtil.isNull(result)){
                            JdHotKeyStore.smartSet(key, "NONE");
                        }else{
                            JdHotKeyStore.smartSet(key, result);
                        }
                        return result;
                    } else {
                        log.info("[Hotlink] key[{}]的值从热点池中返回结果", key);
                        if (String.class.isAssignableFrom(value.getClass()) && "NONE".equals(value.toString())){
                            return null;
                        }
                        return value;
                    }
                }
            }
        }catch (Exception e){
            log.error("[Hotlink] 代理调用出现了未知异常，仍走原调用路径", e);
        }
        return method.invoke(sourceBean, args);
    }

    private static String getFinalKey(String keyPrefix, Object[] args){
        String str;
        if (ObjectUtil.isNull(args) || args.length == 0) {
            str = "ZERO_ARGS";
        }else if (args.length == 1 && (String.class.isAssignableFrom(args[0].getClass()) || ObjectUtil.isBasicType(args[0]))){
            str = args[0].toString();
        }else{
            str = DigestUtil.md5Hex(JSON.toJSONString(args));
        }
        return StrUtil.format("{}|{}", keyPrefix, str);
    }
}
